import {app, BrowserWindow, ipcMain, dialog} from 'electron'
import * as path from 'node:path';
import Store from 'electron-store';
import * as childProcess from 'child_process';
import log, {LogMessage} from 'electron-log';
import { createWindow, createNewWindow, mainWindow as getMainWindow } from './windowManager/WindowManager.ts';
import { setupAutoUpdater, checkForUpdates  } from './services/autoUpdater';
import { GoogleSheetsService } from './services/googleSheets';
import fs from 'fs';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import { pathToFileURL } from 'node:url';
import os from 'os';
import { loginGPO, orderListEntry, reportListEntry } from './operation/playwright-operation/GPO-playwright.ts';
import { EventEmitter } from 'events';
import { pythonEnvironmentService } from './services/pythonEnvironmentService';
import { PythonProcessService } from './services/pythonProcessService';
import { nodeEnvironmentService, NodeEnvironmentStatus, NodeInstallProgress } from './services/nodeEnvironmentService';
import { FileService } from './services/fileService';
import { DocumentService } from './services/documentService';
import { startServer } from '../src/store/pluginMarketService';

const __filename = fileURLToPath(import.meta.url);
export const dname = dirname(__filename);

let isGoogleSheetsInitialized = false;
// mainWindow现在从WindowManager导入

// 控制台信息收集器
class ConsoleCollector extends EventEmitter {
  private logs: Array<{timestamp: number, level: string, message: string}> = [];
  private maxLogs = 1000; // 最大保存日志数量
  
  constructor() {
    super();
    this.setupConsoleCapture();
  }
  
  private formatConsoleArgs(args: any[]): string {
    return args.map(arg => {
      if (typeof arg === 'object' && arg !== null) {
        try {
          return JSON.stringify(arg, null, 2);
        } catch (error) {
          return `[无法序列化的对象: ${error}]`;
        }
      }
      return String(arg);
    }).join(' ');
  }
  
  private setupConsoleCapture() {
    // 保存原始的console方法
    const originalConsole = {
      log: console.log,
      error: console.error,
      warn: console.warn,
      info: console.info,
      debug: console.debug
    };
    
    // 重写console方法
    console.log = (...args) => {
      this.addLog('log', this.formatConsoleArgs(args));
      originalConsole.log.apply(console, args);
    };
    
    console.error = (...args) => {
      this.addLog('error', this.formatConsoleArgs(args));
      originalConsole.error.apply(console, args);
    };
    
    console.warn = (...args) => {
      this.addLog('warn', this.formatConsoleArgs(args));
      originalConsole.warn.apply(console, args);
    };
    
    console.info = (...args) => {
      this.addLog('info', this.formatConsoleArgs(args));
      originalConsole.info.apply(console, args);
    };
    
    console.debug = (...args) => {
      this.addLog('debug', this.formatConsoleArgs(args));
      originalConsole.debug.apply(console, args);
    };
    
    // 监听进程的uncaughtException和unhandledRejection
    process.on('uncaughtException', (error) => {
      this.addLog('error', `Uncaught Exception: ${error.message}\n${error.stack}`);
    });
    
    process.on('unhandledRejection', (reason, promise) => {
      this.addLog('error', `Unhandled Rejection at: ${promise}, reason: ${reason}`);
    });
  }
  
  private addLog(level: string, message: string) {
    const logEntry = {
      timestamp: Date.now(),
      level,
      message
    };
    
    this.logs.push(logEntry);
    
    // 限制日志数量
    if (this.logs.length > this.maxLogs) {
      this.logs.shift();
    }
    
    // 发送实时日志到所有窗口
    this.emit('newLog', logEntry);
    this.broadcastToAllWindows('console-log', logEntry);
  }
  
  private broadcastToAllWindows(channel: string, data: any) {
    BrowserWindow.getAllWindows().forEach(window => {
      if (!window.isDestroyed()) {
        window.webContents.send(channel, data);
      }
    });
  }
  
  getLogs(limit?: number): Array<{timestamp: number, level: string, message: string}> {
    if (limit) {
      return this.logs.slice(-limit);
    }
    return [...this.logs];
  }
  
  clearLogs() {
    this.logs = [];
    this.broadcastToAllWindows('console-cleared', {});
  }
}

// 创建控制台收集器实例
const consoleCollector = new ConsoleCollector();

// 初始化日志库
log.transports.file.level = 'info';
log.transports.console.level = 'info';

// 确保在主进程启动时设置 NODE_ENV
if (!process.env.NODE_ENV) {
    process.env.NODE_ENV = app.isPackaged ? 'production' : 'development';
}
console.log(process.env.NODE_ENV);
console.log('dname:', dname);

process.env.DIST = dname;
process.env.VITE_PUBLIC = app.isPackaged ? process.env.DIST : path.join(process.env.DIST, '../public')
console.log(process.env.VITE_PUBLIC);

// localhost:3000
const VITE_DEV_SERVER_URL = process.env['VITE_DEV_SERVER_URL']

// 初始化electron-store
const store = new Store({
    defaults: {
        sheetIds: [],
        userSettings: {
          name: '',
          email: '',
          site: ''
        }
    }
});

import { downloadPlugin, deletePlugin } from '../src/store/pluginManager';

// 在IPC初始化部分添加：
ipcMain.handle('download-plugin', async (_, pluginId: string, downloadUrl: string) => {
  try {
    await downloadPlugin(pluginId, downloadUrl);
    return { success: true };
  } catch (error: any) {
    return { success: false, error: error.message };
  }
});

ipcMain.handle('delete-plugin', async (_, pluginId: string) => {
  try {
    const pluginPath = path.join(PLUGINS_DIR, pluginId);
    await fs.promises.rm(pluginPath, { recursive: true, force: true });
    return { success: true };
  } catch (error: any) {
    console.error(`删除插件 ${pluginId} 失败:`, error);
    return { success: false, error: error.message };
  }
});

// 项目根目录路径+'src/plugins'
export const PLUGINS_DIR = path.join(process.cwd(), 'src/plugins');

// 初始化Python进程服务
const pythonProcessService = PythonProcessService.getInstance(PLUGINS_DIR);

// 初始化文件服务
const fileService = new FileService(PLUGINS_DIR);

// 初始化文档服务
const documentService = new DocumentService(fileService, PLUGINS_DIR);

ipcMain.handle('get-plugin-html-path', (_, pluginName) => {
  const HTMLpath = path.join(PLUGINS_DIR, pluginName, `${pluginName}.html`);
  return HTMLpath
});

ipcMain.handle('get-plugin-path', (_, pluginName) => {
  const pluginPath = path.join(PLUGINS_DIR, pluginName);
  return pluginPath
});

ipcMain.handle('get-mainfest-path', (_, pluginName) => {
  console.log('PLUGINS_DIR:', PLUGINS_DIR);
  return path.join(
    app.isPackaged 
      ? PLUGINS_DIR 
      : PLUGINS_DIR,
    pluginName,
    'manifest.json'
  );
});

ipcMain.handle('create-plugin-window', (_, {pluginName, htmlPath}) => {
  try {
    if (!htmlPath || !fs.existsSync(htmlPath)) {
        throw new Error(`无效的htmlPath: ${htmlPath}`);
    }
    createNewWindow(pluginName, htmlPath);
} catch (error) {
    console.error('创建插件窗口失败:', error);
}
});

const googleSheetsService = new GoogleSheetsService();

ipcMain.handle('google-api:readColumnData', async (_event, spreadsheetId: string, range: string) => {
    return await googleSheetsService.readColumnData(spreadsheetId, range);
});

ipcMain.handle('execute-child-process', async (_event, command) => {
  try {
    const result = childProcess.execSync(command).toString();
    return result;
  } catch (error: any) {
    throw new Error(`Failed to execute command: ${error.message}`);
  }
});

ipcMain.handle('login-GPO', async (_event, url:string, isHeadless:boolean) => {
  try {
    return await loginGPO(url, isHeadless);
  } catch (error) {
    log.error('Login failed:', error);
    throw error;
  }
});
ipcMain.on('orderList-entry', orderListEntry);
ipcMain.on('reportList-entry', reportListEntry);

// 启动服务端
const startServerAndCreateWindow = async () => {
  try {
    // 启动 Express 服务
    await startServer();
    console.log('服务端已启动');
  } catch (error) {
    console.error('启动服务端失败:', error);
    app.quit(); // 启动失败则退出应用
  }
};

app.whenReady().then(async () =>{
    try {
        createWindow();
        
        // 设置Python环境服务的主窗口引用
        // pythonEnvironmentService.setMainWindow(getMainWindow);
        
        setupAutoUpdater();
        checkForUpdates();
        startServerAndCreateWindow();
        
        // 初始化Python环境服务 - 移除重复调用
        // pythonEnvironmentService.setupIpcHandlers(); // 已在构造函数中调用
        
        // 立即初始化 Google Sheets Entry
        console.log('=== 开始初始化 Google Sheets Entry ===');
        await initGoogleSheetsEntry();
        
    } catch (error) {
        console.error('App initialization error:', error);
        // 即使其他初始化失败，也要尝试初始化 Google Sheets
        try {
            console.log('=== 重试初始化 Google Sheets Entry ===');
            await initGoogleSheetsEntry();
        } catch (retryError) {
            console.error('Google Sheets initialization retry failed:', retryError);
        }
    }
});

// 窗口逻辑
app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

ipcMain.handle('is-window-open', (_, pluginName) => {
  const windows = BrowserWindow.getAllWindows();
  // 检查是否有匹配的插件窗口
  return windows.some(win => {
      // 从窗口标题中移除应用名称后缀，获取纯插件名称
      const winPluginName = win.getTitle().replace(' - Automation Tools Platform', '');
      // 检查窗口名称是否匹配请求的插件名称，并且不是主窗口
      return winPluginName === pluginName && win !== getMainWindow;
    });
});

ipcMain.on('close-window', () => {
  const win = BrowserWindow.getFocusedWindow();
  if (win) {
    win.close();
  }
});

ipcMain.handle('minimize-window', () => {
  const win = BrowserWindow.getFocusedWindow();
  if (win) {
    win.minimize();
  } 
})

ipcMain.handle('toggle-maximize', () => {
  const win = BrowserWindow.getFocusedWindow();
  if (win) {
    if (win.isMaximized()) {
      win.unmaximize();
    } else {
      win.maximize();
    }
  }
})

// 设置逻辑
ipcMain.handle('save-settings', (event, settings) => {
  store.set('userSettings', settings);
});

ipcMain.handle('get-user-settings', async () => {
  const store = new Store();
  return store.get('userSettings') || {};
});

// 获取sheet IDs
ipcMain.handle('getSheetIds', () => {
    return store.get('sheetIds', []);
});

import { sendMonitoringData } from '../electron/operation/usage/user-data';

ipcMain.handle('send-monitoring-data', async (_, data) => {
  await sendMonitoringData(data); // 调用主进程的发送逻辑
});

// 保存sheet IDs
ipcMain.handle('saveSheetIds', (_event, ids: string[]) => {
    store.set('sheetIds', ids);
});

ipcMain.on('log-error', (_, msg) => log.error(msg));
ipcMain.on('log-info', (_, msg) => log.info(msg));

// 控制台信息相关的IPC处理器
ipcMain.handle('get-console-logs', (_, limit?: number) => {
  return consoleCollector.getLogs(limit);
});

ipcMain.handle('clear-console-logs', () => {
  consoleCollector.clearLogs();
  return { success: true };
});

// 开始/停止实时控制台监听
ipcMain.handle('start-console-monitoring', (event) => {
  const window = BrowserWindow.fromWebContents(event.sender);
  if (window) {
    // 发送当前所有日志
    const logs = consoleCollector.getLogs();
    window.webContents.send('console-logs-batch', logs);
  }
  return { success: true };
});

ipcMain.handle('stop-console-monitoring', () => {
  // 这里可以添加停止监听的逻辑，如果需要的话
  return { success: true };
});

// 手动添加日志条目（供其他部分使用）
ipcMain.handle('add-console-log', (_, level: string, message: string) => {
  consoleCollector['addLog'](level, message);
  return { success: true };
});

// 导入googleSheetsEntry
export const initGoogleSheetsEntry = async () => {
  console.log('=== initGoogleSheetsEntry 开始执行 ===');
  if (isGoogleSheetsInitialized) {
    console.log('Google Sheets 已经初始化，跳过');
    return;
  }

  const isProduction = app.isPackaged;
  const baseDir = isProduction 
    ? path.join(process.resourcesPath, 'app') 
    : path.join(dname, '../');
  console.log('baseDir:', baseDir);
  // 修正为平台兼容的路径格式
  const googleSheetsEntryJS = path.join(baseDir, 'src/plugins/google-sheets/googleSheetsEntry.js')
  .replace(/\\/g, '/'); // 统一使用正斜杠
  console.log('JS存在性检查:', fs.existsSync(googleSheetsEntryJS));
  console.log('JS完整路径:', googleSheetsEntryJS);
  if(fs.existsSync(googleSheetsEntryJS)){
    try {
      // 转换为 file:// URL 格式
      const moduleUrl = pathToFileURL(googleSheetsEntryJS).href;
      console.log('JS转换后的URL:', moduleUrl);

      const googleSheetsEntryModule = await import (/* @vite-ignore */ moduleUrl);
      // console.log('googleSheetsEntry imported successfully', Object.keys(googleSheetsEntryModule));
      console.log('googleSheetsEntry imported successfully');
      // 获取导出的函数，支持 CommonJS 和 ES Module 两种导出方式
      const googleSheetsEntry = googleSheetsEntryModule.default || googleSheetsEntryModule;
      // console.log('googleSheetsEntry functions:', Object.keys(googleSheetsEntry));
      console.log('googleSheetsEntry functions')
      ipcMain.handle('getSheetNames', async (_event, spreadsheetId: string) => {
          console.log('IPC handler getSheetNames called with:', spreadsheetId);
          return await googleSheetsEntry.getSheetNames(spreadsheetId);
      });
      ipcMain.handle('google-api:readRowData', async (_event, spreadsheetId, range) => {
          return await googleSheetsEntry.readRowData(spreadsheetId, range);
      });

      ipcMain.handle('google-api:updateRowData', async (_event, spreadsheetId, plmCode, rowData, range) => {
          return await googleSheetsEntry.updateRowData(spreadsheetId, plmCode, rowData, range);
      });

      ipcMain.handle('update-partial-columns', async (_event, spreadsheetId, sheetName, plmCode, updates, range) => {
          try {
              return await googleSheetsEntry.updatePartialColumns(spreadsheetId, sheetName, plmCode, updates, range);
          } catch (error: any) {
              log.error(`Error in updatePartialColumns: ${error.stack || error}`);
              throw error;
          }
      });
      isGoogleSheetsInitialized = true; // 标记为已初始化
      console.log('=== Google Sheets IPC 处理器注册完成 ===');
    }catch (error) {
      console.error('导入googleSheetsEntry失败:', error);
    }
  } else {
    console.error('googleSheetsEntry.js 文件不存在:', googleSheetsEntryJS);
  }
}

// // batch-combine
// import { batchCombine } from '../src/plugins/batch-combine/batch-combine.ts';

// async function doCombine (_event:any, address: string, isHeadless: boolean, orderNumbersArray: string[]) {
//   try {
//     console.log('doCombine called with:', address, isHeadless, orderNumbersArray);
//     const {browser, page, context} = await loginGPO(address, isHeadless);
//     await batchCombine(browser, page, context, orderNumbersArray);
//   }catch (error) {
//     console.error('Error during browser operation:', error);
//     // 返回错误信息
//     return { status: 'error', message: error};
//   }
// }

// ipcMain.handle('run-batch-combine', (event, address: string, isHeadless: boolean, orderNumbersArray: string[]) => {
//   doCombine(event, address, isHeadless, orderNumbersArray);
// });

// new-subcontract
async function getExcelValue(_event:any, e:any) {
  console.log('getExcelValue：', e);
  return e;
}

ipcMain.on('file-input', getExcelValue)

// ipcMain.handle('run-new-subcontract', async (_event, address: string, isHeadless: boolean, allCellData: any) => {
//   try {
//     log.info('开始执行新建分包单流程...');
//     const { browser, page, context } = await loginGPO(address, isHeadless);
//     log.info('GPO登录成功');
//     await newSubcontract(browser, page, context, allCellData);
//   } catch (error: any) {
//     const errorObj = error || {};
//     const errorMessage = errorObj.message || 'Unknown error without message';
//     const errorStack = errorObj.stack || 'No stack trace available';
    
//     // 加固日志输出
//     log.error('新建分包单失败:', JSON.stringify({
//       message: errorMessage,
//       stack: errorStack,
//       rawError: errorObj
//     }));
    
//     return { 
//       status: 'error',
//       message: errorMessage,
//       stack: errorStack
//     };
//   }
// });

ipcMain.handle('process-excel-file', async (_event, fileBuffer) => {
  const XLSX = require('xlsx');
  const workbook = XLSX.read(fileBuffer, {type: 'array'});
  const worksheet = workbook.Sheets[workbook.SheetNames[0]];
  
  // 处理表头
  const getHeader = (sheet: any) => {
    const range = XLSX.utils.decode_range(sheet['!ref']);
    const headers = [];
    for(let C = range.s.c; C <= range.e.c; ++C) {
      const cell = sheet[XLSX.utils.encode_cell({c: C, r: range.s.r})];
      let hdr = cell?.t ? XLSX.utils.format_cell(cell) : `UNKNOWN${C}`;
      headers.push(hdr);
    }
    return headers;
  };

  return {
    headers: getHeader(worksheet),
    data: XLSX.utils.sheet_to_json(worksheet),
    rawWorkbook: workbook
  };
});

ipcMain.handle('read-excel-data', async (_event, fileBuffer) => {
  return await documentService.readExcelData(fileBuffer);
});

ipcMain.handle('read-excel-file', async (_event, filePath) => {
  return await documentService.readExcelFile(filePath);
});

// 处理Word模板相关的IPC请求
ipcMain.handle('get-word-template', (_, pluginName) => {
  return documentService.getWordTemplatePath(pluginName);
});

ipcMain.handle('save-word-file', async (_, buffer, filename) => {
  return await documentService.saveWordFile(buffer, filename);
});

import Docxtemplater from 'docxtemplater';
import PizZip from 'pizzip';

interface ReportDataRow {
  reportNo: string;
  labName: string;
  reportDate: string;
}

ipcMain.handle('process-word-file', async (_event, pluginName, reportData) => {
  return await documentService.processWordFile(pluginName, reportData);
});

ipcMain.handle('get-file-full-path', async (event, file) => {
  return await fileService.getFileFullPath(file);
});

// 获取应用路径
ipcMain.handle('get-app-path', (_, name: string) => {
  return fileService.getAppPath(name);
});

// 获取桌面路径
ipcMain.handle('get-desktop-path', () => {
  return fileService.getDesktopPath();
});

// 确保目录存在
ipcMain.handle('ensure-directory-exists', async (_event, dirPath) => {
  return await fileService.ensureDirectoryExists(dirPath);
});

// 保存文件
ipcMain.handle('save-file', async (_event, filePath, fileContent) => {
  return await fileService.saveFile(filePath, fileContent);
});

// 文件处理
ipcMain.handle('open-file', async (_event, filePath: string) => {
  return await fileService.openFile(filePath);
});

// 下载SubContract模板文件
ipcMain.handle('download-template', async (_event) => {
  const pluginDir = path.join(PLUGINS_DIR, 'new-subcontract');
  if (!fs.existsSync(pluginDir)) {
    throw new Error('未下载插件new-subcontract');
  }
  const resourcesPath = app.isPackaged
       ? path.join(process.cwd(), 'src', 'plugins') // 生产环境
       : PLUGINS_DIR; // 开发环境
  const templateUrl = path.join(
    resourcesPath,
    'new-subcontract',
    'NewSubcontract template.xlsx'
  );

  console.log('模板地址：', templateUrl);
  if (fs.existsSync(templateUrl)) {
    return fs.readFileSync(templateUrl);
  } else {
    throw new Error('Template file not found');
  }
});

ipcMain.on('log-message', (event: Electron.IpcMainEvent, logData?: { type?: string; message?: string; details?: string }) => {
  // 加强类型守卫
  const safeLogData = {
    type: logData?.type || 'info',
    message: logData?.message || '',
    details: logData?.details || ''
  };

  console.log('Received log!:', JSON.stringify(safeLogData));
  console.log('[DEBUG] Sender process:', event.processId);
  
  // 安全访问属性
  console.log('[DEBUG] Raw log data structure:', Object.keys(safeLogData));

  // 确保类型安全
  const validatedType = ['info','warn','error','debug','verbose','silly'].includes(safeLogData.type) ? safeLogData.type : 'info';

  const validatedLogData = {
    message: safeLogData.message.toString(),
    type: validatedType,
    details: safeLogData.details.toString()
  };
  console.log('Validated log:', JSON.stringify(validatedLogData));
  const validTypes = ['info', 'warn', 'error', 'debug', 'verbose', 'silly'];
  const type = validTypes.includes(validatedLogData.type) ? validatedLogData.type : 'info';
    
  // 添加类型断言解决electron-log类型问题
  (log[type as keyof typeof log] as (message: string) => void)(validatedLogData.message);

  if (event.sender) {
      BrowserWindow.getAllWindows().forEach(win => {
          if (win.webContents !== event.sender) {
              win.webContents.send('log-message', validatedLogData);
          }
      });
  }
});

import axios from 'axios';
import extract from 'extract-zip';
import semver from 'semver';
import { glob } from 'glob';

ipcMain.handle('check-plugin-update', async (_, pluginId) => {
  try {
    const localManifestPath = path.join(PLUGINS_DIR, pluginId, 'manifest.json');

    delete require.cache[require.resolve(localManifestPath)];
    const localManifest = require(localManifestPath);

    console.log('本地版本：', localManifest.version);

    // 下载压缩包到临时目录
    const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'plugin-update-'));
    const zipPath = path.join(tempDir, `${pluginId}.zip`);
    const response = await axios({
      url: `http://10.169.128.20/files/plugins/${pluginId}.zip`,
      responseType: 'arraybuffer',
    });
    fs.writeFileSync(zipPath, response.data);

    // 解压并读取manifest
    await extract(zipPath, { dir: tempDir  });
    
    const manifestSearchPath = path.join(tempDir, '**', 'manifest.json');
    const manifestPaths = await glob(manifestSearchPath, { windowsPathsNoEscape: true });

    if (manifestPaths.length === 0) {
      throw new Error(`在压缩包中找不到manifest.json，搜索路径：${manifestSearchPath}`);
    }
    const remoteManifest = require(manifestPaths[0]);
    console.log('远程版本：', remoteManifest.version);

    // 清理临时文件
    fs.rmSync(tempDir, { recursive: true, force: true });

    // 版本比较
    return semver.gt(remoteManifest.version, localManifest.version);
  } catch (error) {
    console.error('更新检查失败:', error);
    return false;
  }
});

// 调用python-exe
ipcMain.handle('run-pyexe', async (event, params: { exeName?: string, args?: any[], pluginName?: string }) => {
  try {
    // 获取可执行文件名
    const exeName = params.exeName;
    const args = params.args || [];
    
    if (!exeName) {
      throw new Error('未指定可执行文件名');
    }
    
    // 构建可执行文件路径
    let exePath;
    if (params.pluginName) {
      // 从插件的dist目录获取可执行文件
      exePath = path.join(PLUGINS_DIR, params.pluginName, 'dist', exeName);
      if (!fs.existsSync(exePath)) {
        throw new Error(`可执行文件不存在: ${exePath}`);
      }
    } else {
      throw new Error('未指定插件名称');
    }
    
    console.log(`执行可执行文件: ${exePath}，参数:`, args);

    return new Promise((resolve) => {
      const exeProcess = childProcess.spawn(exePath, args, {
        // 确保输出是无缓冲的
        stdio: ['pipe', 'pipe', 'pipe']
      });
      
      let output = '';
      let errorOutput = '';

      // 实时处理stdout输出
      exeProcess.stdout.on('data', (data) => {
        const dataStr = data.toString();
        output += dataStr;
        
        // 实时发送日志到渲染进程
        event.sender.send('python-log-output', {
          type: 'stdout',
          data: dataStr,
          timestamp: new Date().toISOString()
        });
      });

      // 实时处理stderr输出
      exeProcess.stderr.on('data', (data) => {
        const dataStr = data.toString();
        errorOutput += dataStr;
        
        // 实时发送错误日志到渲染进程
        event.sender.send('python-log-output', {
          type: 'stderr',
          data: dataStr,
          timestamp: new Date().toISOString()
        });
      });

      // 处理进程结束事件
      exeProcess.on('close', (code) => {
        // 发送进程结束信号
        event.sender.send('python-process-ended', {
          code,
          success: code === 0,
          timestamp: new Date().toISOString()
        });
        
        if (code !== 0) {
          console.error(`可执行文件退出，退出码 ${code}: ${errorOutput}`);
          resolve({ 
            success: false, 
            error: errorOutput || `可执行文件执行失败，退出码: ${code}`,
            output: output
          });
        } else {
          resolve({ 
            success: true,
            message: '可执行文件执行成功',
            data: output
          });
        }
      });

      exeProcess.on('error', (err) => {
        console.error('启动子进程失败.', err);
        
        // 发送进程错误信号
        event.sender.send('python-process-error', {
          error: err.message,
          timestamp: new Date().toISOString()
        });
        
        resolve({
          success: false,
          error: `启动可执行文件子进程失败: ${err.message}`
        });
      });
    });
  } catch (error: any) {
    console.error('执行可执行文件出错:', error);
    return {
      success: false,
      error: error.message || '未知错误'
    };
  }
})

ipcMain.handle('run-pyfile', async (event, params: { scriptPath?: string, filePath?: string, fileName?: string, args?: any[], pluginName?: string }) => {
  return await pythonProcessService.executePythonScript(event, params);
});


// 文件下载处理
ipcMain.on('download-file', (_, filePath) => {
  const { shell } = require('electron');
  shell.showItemInFolder(filePath);
});

// 在文件夹中显示文件
ipcMain.handle('show-item-in-folder', async (_event, filePath: string) => {
  return await fileService.showItemInFolder(filePath);
});

const { fork } = require('child_process');

// 存储正在运行的插件脚本任务，用于停止功能
const runningPluginTasks = new Map();

// 将runningPluginTasks暴露给全局对象，以便其他模块可以访问
(global as any).runningPluginTasks = runningPluginTasks;

// 添加IPC处理器，用于获取正在运行的插件任务
ipcMain.handle('get-running-plugin-tasks', () => {
  return Array.from(runningPluginTasks.entries());
});

ipcMain.handle('run-plugin-script', async (event, { pluginName, script, args = [] }) => {
  console.log('Received plugin script request:', {pluginName, script, args});  
  try {
        const scriptPath = path.join(PLUGINS_DIR, pluginName, script);
        const taskId = `${pluginName}-${script}-${Date.now()}`;
        
        // 清除缓存确保每次都是最新导入
        delete require.cache[require.resolve(scriptPath)];

        // 使用 require 导入 CommonJS 模块
        const pluginModule = require(scriptPath);
        
        // 创建一个可取消的Promise
        const controller = new AbortController();
        const signal = controller.signal;
        
        // 存储任务信息
        runningPluginTasks.set(taskId, {
          controller,
          pluginName,
          script
        });
        
        // 发送任务ID给渲染进程
        event.sender.send('plugin-script-started', { taskId });
        
        // 检查模块是否支持中断信号
        if (pluginModule.runWithSignal && typeof pluginModule.runWithSignal === 'function') {
          console.log(`插件 ${pluginName}/${script} 支持中断信号，使用 runWithSignal 方法`);
          
          try {
            // 使用支持中断的方法
            const result = await pluginModule.runWithSignal(signal, ...args);
            // 任务完成后从Map中移除
            runningPluginTasks.delete(taskId);
            return { success: true, data: result, taskId };
          } catch (error) {
            // 检查是否是由于中断导致的错误
            if (signal.aborted) {
              console.log(`任务 ${taskId} 已被用户取消`);
              // 任务完成后从Map中移除
              runningPluginTasks.delete(taskId);
              return { success: false, error: '任务已被用户取消', taskId };
            }
            
            // 其他错误
            console.error(`执行插件脚本失败: ${error}`);
            // 任务完成后从Map中移除
            runningPluginTasks.delete(taskId);
            return { success: false, error: (error as Error).message };
          }
        } else {
          // 不支持中断信号的旧版插件
          console.log(`插件 ${pluginName}/${script} 不支持中断信号，使用标准方法`);
          
          let pluginFunction;
          if (typeof pluginModule === 'function') {
            // 如果模块直接导出函数
            pluginFunction = pluginModule;
          } else if (pluginModule.default && typeof pluginModule.default === 'function') {
            // 如果是 ES 模块默认导出
            pluginFunction = pluginModule.default;
          } else {
            throw new Error('插件脚本必须导出一个函数');
          }
          
          // 创建一个可以被中断的Promise
          const taskPromise = new Promise(async (resolve, reject) => {
            try {
              if (signal.aborted) {
                reject(new Error('任务已被取消'));
                return;
              }
              
              // 调用插件函数并传递参数
              const result = await pluginFunction(...args);
              resolve(result);
            } catch (error) {
              reject(error);
            } finally {
              // 任务完成后从Map中移除
              runningPluginTasks.delete(taskId);
            }
          });
          
          // 监听中断信号
          signal.addEventListener('abort', () => {
            console.log(`任务 ${taskId} 被中断，但插件可能不会立即响应`);
          });
          
          try {
            const result = await taskPromise;
            return { success: true, data: result, taskId };
          } catch (error) {
            if (signal.aborted) {
              return { success: false, error: '任务已被用户取消', taskId };
            }
            throw error;
          }
        }
    } catch (error: any) {
        console.error(`执行插件脚本失败: ${error}`);
        return { success: false, error: error.message };
    }
});

// 处理停止插件脚本的请求
ipcMain.handle('stop-plugin-script', async (event, { taskId }) => {
  console.log(`收到停止脚本请求: ${taskId}`);
  
  if (!taskId) {
    return { success: false, error: '未提供任务ID' };
  }
  
  const task = runningPluginTasks.get(taskId);
  if (!task) {
    return { success: false, error: '找不到指定的任务' };
  }
  
  try {
    // 中断任务
    task.controller.abort();
    console.log(`已中断任务: ${taskId}`);
    
    // 从Map中移除任务
    runningPluginTasks.delete(taskId);
    
    return { success: true, message: '任务已停止' };
  } catch (error: any) {
    console.error(`停止任务失败: ${error}`);
    return { success: false, error: error.message };
  }
});

// 读取目录
ipcMain.handle('read-directory', async (_event, dirPath) => {
  const result = await fileService.readDirectory(dirPath);
  if (result.success) {
    return result.data; // 返回文件数组而不是整个结果对象
  } else {
    throw new Error(result.error || '读取目录失败');
  }
});

// 读取文件
ipcMain.handle('read-file', async (_event, filePath) => {
  const result = await fileService.readFile(filePath);
  return result; // 返回完整的结果对象，包含success、data和error字段
});

// 写入文件
ipcMain.handle('write-file', async (_event, filePath, content) => {
  return await fileService.writeFile(filePath, content);
});

// 删除文件
ipcMain.handle('delete-file', async (_event, filePath) => {
  return await fileService.deleteFile(filePath);
});

// 文件选择对话框
ipcMain.handle('show-open-dialog', async (_event, options) => {
  return await fileService.showOpenDialog(getMainWindow, options);
});

// 检查文件是否存在
ipcMain.handle('check-file-exists', async (_event, filePath) => {
  return await fileService.checkFileExists(filePath);
});

// Node.js环境检查相关IPC处理器
ipcMain.handle('check-node-environment', async () => {
  try {
    const status = await nodeEnvironmentService.checkNodeEnvironment();
    return { success: true, data: status };
  } catch (error: any) {
    return { success: false, error: error.message };
  }
});

ipcMain.handle('install-portable-node', async (event) => {
  try {
    const result = await nodeEnvironmentService.installPortableNode((progress: NodeInstallProgress) => {
      // 向渲染进程发送安装进度
      event.sender.send('node-install-progress', progress);
    });
    return result;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
});

ipcMain.handle('check-plugin-dependencies', async (event, pluginPath: string) => {
  try {
    const result = await nodeEnvironmentService.checkAndInstallPluginDependencies(
      pluginPath,
      (message: string, progress: number) => {
        // 向渲染进程发送依赖安装进度
        event.sender.send('plugin-dependency-progress', { message, progress });
      }
    );
    return result;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
});

ipcMain.handle('get-node-executable-path', async () => {
  try {
    const nodePath = nodeEnvironmentService.getNodeExecutablePath();
    const npmPath = nodeEnvironmentService.getNpmExecutablePath();
    return {
      success: true,
      data: {
        nodePath,
        npmPath
      }
    };
  } catch (error: any) {
    return { success: false, error: error.message };
  }
});